//------------------------------------------------------------------------------
// Copyright (c) 2008 www.dnaide.com
// Licensed under the MIT (MIT-LICENSE.txt)
//------------------------------------------------------------------------------
using System;
using System.Globalization;

namespace DNAide.Core
{
	public static partial class CastAide
	{

		#region DateTime

		/// <summary>
		/// Returns an object as a DateTime.
		/// </summary>
		/// <param name="value">Value to cast</param>
		/// <returns>DateTime</returns>
		/// <remarks>
		/// <para>
		/// Will return DateTime.Now if the cast fails.
		/// </para>
		/// <para>
		/// Uses CultureInfo.CurrentCulture.
		/// </para>
		/// </remarks>
		public static DateTime AsDateTime(object value)
		{
			return AsDateTime(value, DateTime.Now, CultureInfo.CurrentCulture);
		}


		/// <summary>
		/// Returns an object as a DateTime.
		/// </summary>
		/// <param name="value">Value to cast</param>
		/// <param name="defaultValue">Value returned if cast fails</param>
		/// <returns>DateTime</returns>
		/// <remarks>
		/// <para>
		/// Uses CultureInfo.CurrentCulture.
		/// </para>
		/// </remarks>
		public static DateTime AsDateTime(object value, DateTime defaultValue)
		{
			return AsDateTime(value, defaultValue, CultureInfo.CurrentCulture);
		}


		/// <summary>
		/// Returns an object as a DateTime.
		/// </summary>
		/// <param name="value">Value to cast</param>
		/// <param name="provider">Instance of IFormatProvider</param>
		/// <returns>DateTime</returns>
		/// <remarks>
		/// <para>
		/// Will return false if the cast fails.
		/// </para>
		/// </remarks>
		public static DateTime AsDateTime(object value, IFormatProvider provider)
		{
			return AsDateTime(value, DateTime.Now, provider);
		}


		/// <summary>
		/// Returns an object as a DateTime.
		/// </summary>
		/// <param name="value">Value to cast</param>
		/// <param name="defaultValue">Value returned if cast fails</param>
		/// <param name="provider">Instance of IFormatProvider</param>
		/// <returns>DateTime</returns>
		public static DateTime AsDateTime(object value, DateTime defaultValue, IFormatProvider provider)
		{
			if (value == null || value == System.DBNull.Value)
				return defaultValue;

			if (provider == null)
				provider = CultureInfo.CurrentCulture;

			DateTime retval;

			try
			{
				retval = Convert.ToDateTime(value, provider);
			}
			catch (InvalidCastException)
			{
				retval = defaultValue;
			}
			catch (FormatException)
			{
				retval = defaultValue;
			}
			return retval;
		}


		/// <summary>
		/// Returns an object as a DateTime using the invariant culture.
		/// </summary>
		/// <param name="value">Value to cast</param>
		/// <returns>DateTime</returns>
		/// <remarks>
		/// <para>
		/// Will return DateTime.Now if the cast fails.
		/// </para>
		/// </remarks>
		public static DateTime AsDateTimeInvariant(object value)
		{
			return AsDateTime(value, DateTime.Now, CultureInfo.InvariantCulture);
		}


		/// <summary>
		/// Returns an object as a DateTime using the invariant culture.
		/// </summary>
		/// <param name="value">Value to cast</param>
		/// <param name="defaultValue">Value returned if cast fails</param>
		/// <returns>DateTime</returns>
		public static DateTime AsDateTimeInvariant(object value, DateTime defaultValue)
		{
			return AsDateTime(value, defaultValue, CultureInfo.InvariantCulture);
		}

		#endregion


		#region DateTimeWithFormat

		/// <summary>
		/// Returns an object as a DateTime.
		/// </summary>
		/// <param name="value">Value to cast</param>
		/// <param name="format">String format</param>
		/// <returns>DateTime</returns>
		/// <remarks>
		/// <para>
		/// Will return DateTime.Now if the cast fails.
		/// </para>
		/// <para>
		/// Uses CultureInfo.CurrentCulture.
		/// </para>
		/// </remarks>
		public static DateTime AsDateTimeWithFormat(object value, string format)
		{
			return AsDateTimeWithFormat(value, format, DateTime.Now, CultureInfo.CurrentCulture);
		}


		/// <summary>
		/// Returns an object as a DateTime.
		/// </summary>
		/// <param name="value">Value to cast</param>
		/// <param name="format">String format</param>
		/// <param name="defaultValue">Value returned if cast fails</param>
		/// <returns>DateTime</returns>
		/// <remarks>
		/// <para>
		/// Uses CultureInfo.CurrentCulture.
		/// </para>
		/// </remarks>
		public static DateTime AsDateTimeWithFormat(object value, string format, DateTime defaultValue)
		{
			return AsDateTimeWithFormat(value, format, defaultValue, CultureInfo.CurrentCulture);
		}


		/// <summary>
		/// Returns an object as a DateTime.
		/// </summary>
		/// <param name="value">Value to cast</param>
		/// <param name="format">String format</param>
		/// <param name="provider">Instance of IFormatProvider</param>
		/// <returns>DateTime</returns>
		/// <remarks>
		/// <para>
		/// Will return DateTime.Now if the cast fails.
		/// </para>
		/// </remarks>
		public static DateTime AsDateTimeWithFormat(object value, string format, IFormatProvider provider)
		{
			return AsDateTimeWithFormat(value, format, DateTime.Now, provider);
		}


		/// <summary>
		/// Returns an object as a DateTime.
		/// </summary>
		/// <param name="value">Value to cast</param>
		/// <param name="format">String format</param>
		/// <param name="defaultValue">Value returned if cast fails</param>
		/// <param name="provider">Instance of IFormatProvider</param>
		/// <returns>DateTime</returns>
		public static DateTime AsDateTimeWithFormat(object value, string format, DateTime defaultValue, IFormatProvider provider)
		{
			if (value == null || value == System.DBNull.Value)
				return defaultValue;

			if (provider == null)
				provider = CultureInfo.CurrentCulture;

			DateTime retval;

			try
			{
				retval = DateTime.ParseExact(AsString(value, provider), format, provider);
			}
			catch (InvalidCastException)
			{
				retval = defaultValue;
			}
			catch (FormatException)
			{
				retval = defaultValue;
			}
			return retval;
		}


		/// <summary>
		/// Returns an object as a DateTime using the invariant culture.
		/// </summary>
		/// <param name="value">Value to cast</param>
		/// <param name="format">String format</param>
		/// <returns>DateTime</returns>
		/// <remarks>
		/// <para>
		/// Will return DateTime.Now if the cast fails.
		/// </para>
		/// </remarks> 
		public static DateTime AsDateTimeWithFormatInvariant(object value, string format)
		{
			return AsDateTimeWithFormat(value, format, DateTime.Now, CultureInfo.CurrentCulture);
		}


		/// <summary>
		/// Returns an object as a DateTime using the invariant culture.
		/// </summary>
		/// <param name="value">Value to cast</param>
		/// <param name="format">String format</param>
		/// <param name="defaultValue">Value returned if cast fails</param>
		/// <returns>DateTime</returns>
		public static DateTime AsDateTimeWithFormatInvariant(object value, string format, DateTime defaultValue)
		{
			return AsDateTimeWithFormat(value, format, defaultValue, CultureInfo.InvariantCulture);
		}


		#endregion

	}
}
